#
#        Python GUI - Properties - Generic - heavily modified Jython version
#

##*change* this file was totally rewritten...

class object: #Hack until Jython does new-style classes
    def __init__(self):
        self._process_properties(self.__class__)
    
    def _process_properties(self,_class):
        for key in _class.__dict__.keys():
            value=_class.__dict__[key]
            if key.startswith("_property_"): continue
            if isinstance(value,property):
                _class.__dict__["_property_"+key]=value
                del _class.__dict__[key] #Force attribute access to go to __getattr__
        for base in _class.__bases__:
            self._process_properties(base)

    def __getattr__(self,name):
        if name.startswith("_property_"): raise AttributeError,name
        if hasattr(self,"_property_"+name):
            p=getattr(self,"_property_"+name)
            if isinstance(p,overridable_property):
                if not hasattr(self,p.getter_name): raise Exception,"There is no getter function for "+name+". Should be called "+p.getter_name
                try:
                    return getattr(self,p.getter_name)()
                except Exception,e:
                    raise Exception, "Error in property get: %s"%e
            else:
                return p.get()
        
        raise AttributeError,name
    
    def __setattr__(self,name,value):
        if hasattr(self,"_property_"+name):
            p=getattr(self,"_property_"+name)
            if isinstance(p,overridable_property):
                if not hasattr(self,p.setter_name): raise Exception,"There is no setter function for "+name+". Should be called "+p.setter_name
                getattr(self,p.setter_name)(value)
            else:
                p.set(value)
            return
            
        self.__dict__[name]=value
    
    def __delattr__(self,name):
        if hasattr(self,"_property_"+name):
            p=getattr(self,"_property_"+name)
            p.delete()
            return
        
        del self.__dict__[name]

class property: #Hack until Jython does new-style classes
    def __init__(self,getter=None,setter=None,deleter=None,doc=None):
        self.getter=getter
        self.setter=setter
        self.deleter=deleter
        self.doc=doc
    def get(self):
        return self.getter()
    def set(self,value):
        self.setter(value)
    def delete(self):
        self.deleter()

class Properties(object):
    """
    This class implements the standard interface for initialising
    properties using keyword arguments.
    """

    def __init__(self, **kw):
        "Properties(name=value, ...) passes the given arguments to the set() method."
        object.__init__(self)
        self.set(**kw)

    def set(self, **kw):
        """set(name=value, ...) sets property values according to the given 
        keyword arguments."""
        for name in kw.keys():
            value=kw[name]
            getattr(self, 'set_' + name)(value)


class overridable_property(property):
    """Creates a property which calls methods get_xxx and set_xxx of
    the underlying object to get and set the property value, so that
    the property's behaviour may be easily overridden by subclasses."""
    def __init__(self, name, doc = None):
        self.getter_name = intern('get_' + name)
        self.setter_name = intern('set_' + name)